#include "Precomp.h"
#include "ltGraphicManager.h"
#include <string>

namespace Lotus
{
	LT_IMPLEMENT_SINGLETON(GraphicManager);

	GraphicManager::GraphicManager()
		:OgreRoot(NULL),OgreRenderWindow(NULL),run(true)
	{
	}

	bool GraphicManager::init(const char* WindowTitle)
	{
		OgreRoot = new Ogre::Root("configs/plugins.cfg", "configs/Game.cfg", "logs/ogre.log");
		if(!OgreRoot->restoreConfig())
			if(!OgreRoot->showConfigDialog())
				return false;

		OgreRenderWindow = OgreRoot->initialise(true, WindowTitle);
		OgreRenderWindow->addViewport(0);
		OgreRoot->addFrameListener(this);
		loadResources();
		return true;
	}

	bool GraphicManager::init(RenderAPI api, const char* WindowTitle, unsigned int Width, unsigned int Height, bool FullScreen)
	{
		OgreRoot = new Ogre::Root("configs/plugins.cfg", "configs/Game.cfg", "logs/ogre.log");

		/// Chose render API
		Ogre::RenderSystemList* rList = OgreRoot->getAvailableRenderers();
		Ogre::RenderSystemList::const_iterator rItr;
		switch(api)
		{
		case Direct3D9:
			for(rItr = rList->begin(); rItr != rList->end(); rItr++)
			{
				if((*rItr)->getName() == "Direct3D9 Rendering Subsystem")
					break;
			}
			break;
		case OpenGL:
			for(rItr = rList->begin(); rItr != rList->end(); rItr++)
			{
				if((*rItr)->getName() == "OpenGL Rendering Subsystem")
					break;
			}
			break;
		}
		if(rItr == rList->end())
		{
			MessageBox(NULL, L"Rendering API not found", L"Sorry!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
			return false;//! Error
		}
		else
		{
			OgreRoot->setRenderSystem((*rItr));
		}
		OgreRoot->initialise(false);

		/// Create render window
		Ogre::NameValuePairList param;
		param["title"] = WindowTitle;
		OgreRenderWindow = OgreRoot->createRenderWindow("Main", Width, Height, FullScreen, &param);
		OgreRenderWindow->addViewport(0);
		OgreRoot->addFrameListener(this);
		loadResources();
		return true;
	}

	void GraphicManager::stopRendering()
	{
		run = false;
	}

	GraphicManager::~GraphicManager()
	{
		OgreRoot->removeFrameListener(this);

		if(OgreRoot)
			delete OgreRoot;
	}

	Ogre::Root* GraphicManager::getOgreRoot() const
	{
		return OgreRoot;
	}

	Ogre::RenderWindow* GraphicManager::getOgreRenderWindow() const
	{
		return OgreRenderWindow;
	}

	bool GraphicManager::frameStarted(const Ogre::FrameEvent& evt)
	{
		FrameStartedEvent(evt);
		return true;
	}

	bool GraphicManager::frameRenderingQueued(const Ogre::FrameEvent& evt)
	{
		FrameRenderingQueuedEvent(evt);
		return !OgreRenderWindow->isClosed() && run;
	}

	bool GraphicManager::frameEnded(const Ogre::FrameEvent& evt)
	{
		FrameEndedEvent(evt);
		return true;
	}

	void GraphicManager::loadResources()
	{
		Ogre::ConfigFile cf;
		cf.load("Configs/resources.cfg");
		Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
		Ogre::String secName, typeName, archName;
		while (seci.hasMoreElements())
		{
			secName = seci.peekNextKey();
			Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
			Ogre::ConfigFile::SettingsMultiMap::iterator i;
			for (i = settings->begin(); i != settings->end(); ++i)
			{
				typeName = i->first;
				archName = i->second;
				Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName);
			}
		}
		Ogre::ResourceGroupManager::getSingletonPtr()->initialiseResourceGroup(Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	}
}